<template>
  <el-main class="backtest-container">
    <!-- 筛选控件区域 -->
    <div class="controls-container">
      <el-row :gutter="20" align="middle">
        <el-col :span="4">
          <el-select 
            v-model="indexSelected" 
            placeholder="请选择指数" 
            filterable
            clearable
            @change="handleIndexChange"
          >
            <el-option 
              v-for="item in indexOptions" 
              :key="item.dm"
              :label="`${item.mc}（${item.jys}）`"
              :value="item.dm"
            ></el-option>
          </el-select>
        </el-col>
        <el-col :span="5">
          <el-date-picker
            v-model="dateRange"
            type="daterange"
            start-placeholder="开始日期"
            end-placeholder="结束日期"
            placeholder="选择数据集范围（训练期）"
            :disabled-date="(date) => date > new Date()"
            value-format="YYYY-MM-DD"
            range-separator="至"
          />
        </el-col>
        <el-col :span="4">
          <el-date-picker
            v-model="testDate"
            type="date"
            placeholder="选择测试集结束日期"
            :disabled-date="getTestDateDisabled"
            value-format="YYYY-MM-DD"
          />
        </el-col>
        <el-col :span="4">
          <el-select 
            v-model="strategySelected" 
            placeholder="请选择策略" 
            clearable
          >
            <el-option label="均线策略（5日/20日）" value="moving-average"></el-option>
            <el-option label="动量策略" value="momentum"></el-option>
            <el-option label="均值回归" value="mean-reversion"></el-option>
          </el-select>
        </el-col>
        <el-col :span="3">
          <el-button 
            type="primary" 
            @click="startTest"
            style="width: 100%;"
          >
            开始测试
          </el-button>
        </el-col>
      </el-row>
    </div>

    <!-- 图表区域：修复最大值文案+新增买卖标记 -->
    <div class="chart-container-group">
      <div class="chart-item">
        <div class="chart-header">
          <h3>指数收盘价走势（蓝色：数据集 | 红色：测试集 | 绿B：买入 | 红S：卖出）</h3>
          <div class="chart-tags">
            <el-tag size="small" v-if="Array.isArray(dateRange) && dateRange.length === 2">
              数据集：{{ dateRange[0] }} - {{ dateRange[1] }}
            </el-tag>
            <el-tag size="small" type="warning" v-if="Array.isArray(dateRange) && dateRange.length === 2 && testDate">
              测试集：{{ getTestStartDate() }} - {{ testDate }}
            </el-tag>
            <el-tag size="small" type="info" v-if="chartMarkers.datasetMax.value">
              数据集最高：{{ chartMarkers.datasetMax.value.toFixed(2) }}元（{{ chartMarkers.datasetMax.date }}）
            </el-tag>
            <el-tag size="small" type="info" v-if="chartMarkers.datasetMin.value">
              数据集最低：{{ chartMarkers.datasetMin.value.toFixed(2) }}元（{{ chartMarkers.datasetMin.date }}）
            </el-tag>
            <el-tag size="small" type="info" v-if="chartMarkers.testsetMax.value">
              测试集最高：{{ chartMarkers.testsetMax.value.toFixed(2) }}元（{{ chartMarkers.testsetMax.date }}）
            </el-tag>
            <el-tag size="small" type="info" v-if="chartMarkers.testsetMin.value">
              测试集最低：{{ chartMarkers.testsetMin.value.toFixed(2) }}元（{{ chartMarkers.testsetMin.date }}）
            </el-tag>
          </div>
        </div>
        <div id="priceChartContainer" ref="priceChartRef" class="chart-content"></div>
      </div>
    </div>

    <!-- 回测结果表格 -->
    <div class="backtest-result-container">
      <div class="result-header">
        <h3>回测操作记录（{{ strategySelected ? '均线策略（5日/20日）' : '未选择策略' }}）</h3>
        <div class="result-summary" v-if="backtestTableData.length > 0">
          <el-descriptions :column="3" border>
            <el-descriptions-item label="初始资金">10,000.00 元</el-descriptions-item>
            <el-descriptions-item label="最终总资产">
              <span :style="finalTotal > 10000 ? 'color: #67c23a' : 'color: #f56c6c'">
                {{ finalTotal.toFixed(2) }} 元
              </span>
            </el-descriptions-item>
            <el-descriptions-item label="总收益率">
              <span :style="totalReturnRate > 0 ? 'color: #67c23a' : 'color: #f56c6c'">
                {{ totalReturnRate.toFixed(2) }}%
              </span>
            </el-descriptions-item>
          </el-descriptions>
        </div>
      </div>
      <el-table :data="backtestTableData" border style="width: 100%" :empty-text="isBacktestDone ? '测试期内无交易操作（仅显示最后一天资产情况）' : '点击开始测试生成记录'">
        <el-table-column prop="date" label="日期" width="160" align="center" />
        <el-table-column prop="operation" label="操作" width="120" align="center">
          <template #default="scope">
            <el-tag :type="scope.row.operation === '买入' ? 'success' : (scope.row.operation === '卖出' ? 'danger' : 'info')">
              {{ scope.row.operation }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column prop="closePrice" label="收盘价(元)" width="140" align="center" />
        <el-table-column prop="share" label="交易份数" width="140" align="center" />
        <el-table-column prop="cash" label="现金(元)" width="140" align="center" />
        <el-table-column prop="fundValue" label="持仓价值(元)" width="160" align="center" />
        <el-table-column prop="total" label="总资产(元)" width="160" align="center">
          <template #default="scope">
            <span :style="scope.row.total > 10000 ? 'color: #67c23a' : 'color: #f56c6c'">
              {{ scope.row.total }}
              <el-tooltip content="总资产=现金+持仓价值" placement="top">
                <i class="el-icon-question" style="margin-left:4px;font-size:12px;"></i>
              </el-tooltip>
            </span>
          </template>
        </el-table-column>
        <el-table-column prop="returnRate" label="累计收益率" width="160" align="center">
          <template #default="scope">
            <span :style="scope.row.returnRate > 0 ? 'color: #67c23a' : 'color: #f56c6c'">
              {{ scope.row.returnRate.toFixed(2) }}%
            </span>
          </template>
        </el-table-column>
      </el-table>
    </div>
  </el-main>
</template>

<script setup>
import { ref, onMounted, nextTick, watch, getCurrentInstance } from 'vue'
import { ElMessage, ElLoading, ElTag, ElDescriptions, ElDescriptionsItem, ElTooltip } from 'element-plus'
import * as echarts from 'echarts'

const instance = getCurrentInstance()
const $axios = instance?.appContext.config.globalProperties.$axios

// 响应式数据
const indexSelected = ref('')
const indexOptions = ref([])
const dateRange = ref([])
const testDate = ref('')
const strategySelected = ref('')
const priceChartRef = ref(null)
const priceChartInstance = ref(null)
const priceChartData = ref([])
const isBacktestDone = ref(false)
const backtestTableData = ref([])
const finalTotal = ref(10000)
const totalReturnRate = ref(0)
const chartMarkers = ref({
  datasetMax: { value: null, date: '' },
  datasetMin: { value: null, date: '' },
  testsetMax: { value: null, date: '' },
  testsetMin: { value: null, date: '' }
})

// 均线策略参数
const MA_PARAMS = {
  shortPeriod: 5,
  longPeriod: 20
}

// 计算测试集开始日期
const getTestStartDate = () => {
  if (!Array.isArray(dateRange.value) || dateRange.value.length !== 2) return ''
  
  const rangeEnd = dateRange.value[1]
  const endDate = new Date(rangeEnd)
  endDate.setDate(endDate.getDate() + 1)
  return endDate.toISOString().split('T')[0]
}

// 测试日期禁用逻辑
const getTestDateDisabled = (date) => {
  if (!Array.isArray(dateRange.value) || dateRange.value.length !== 2) return true
  
  const rangeEnd = new Date(dateRange.value[1])
  return date > new Date() || date <= rangeEnd
}

// 日期格式化工具
const formatDateToYmdNum = (dateStr) => {
  if (!dateStr || typeof dateStr !== 'string') return ''
  const dateRegex = /^\d{4}-\d{2}-\d{2}$/
  if (!dateRegex.test(dateStr)) {
    console.warn('无效的日期格式（需YYYY-MM-DD）:', dateStr)
    return ''
  }
  return dateStr.replace(/-/g, '')
}

const formatDateToYmd = (tValue) => {
  if (!tValue) return ''
  const tStr = String(tValue)
  if (tStr.length === 8 && /^\d{8}$/.test(tStr)) {
    const year = tStr.slice(0,4)
    const month = tStr.slice(4,6)
    const day = tStr.slice(6,8)
    if (Number(month) > 0 && Number(month) <= 12 && Number(day) > 0 && Number(day) <= 31) {
      return `${year}-${month}-${day}`
    } else {
      console.warn('无效的8位日期:', tStr)
      return ''
    }
  }
  const dateObj = new Date(tValue)
  if (isNaN(dateObj.getTime())) {
    console.warn('无效的日期值:', tValue)
    return ''
  }
  return `${dateObj.getFullYear()}-${String(dateObj.getMonth() + 1).padStart(2, '0')}-${String(dateObj.getDate()).padStart(2, '0')}`
}

// 加载指数列表
const fetchIndexList = async () => {
  if (!instance || !$axios) return

  const loading = ElLoading.service({
    text: '正在加载指数列表...',
    target: '.controls-container',
    background: 'rgba(255, 255, 255, 0.7)'
  })

  try {
    const res = await $axios.get('https://api.zhituapi.com/hz/list/hszs', {
      params: { token: 'ZHITU_TOKEN_LIMIT_TEST' }
    })
    const indexData = res.data || []
    if (Array.isArray(indexData) && indexData.length > 0) {
      indexOptions.value = indexData
      indexSelected.value = indexData[0].dm
      ElMessage.success(`成功加载${indexData.length}个指数`)
    } else {
      ElMessage.warning('未获取到指数数据')
      indexOptions.value = []
    }
  } catch (error) {
    console.error('指数列表加载失败：', error)
    ElMessage.error(`指数加载失败：${error.message || '网络异常'}`)
  } finally {
    loading.close()
  }
}

// 均线计算工具函数
const calculateMA = (allData, targetDate, period) => {
  if (!Array.isArray(allData) || allData.length < period) return null
  
  const targetIndex = allData.findIndex(item => item.date === targetDate)
  if (targetIndex === -1 || targetIndex < period - 1) {
    return null
  }

  const recentData = allData.slice(targetIndex - period + 1, targetIndex + 1)
  const sum = recentData.reduce((acc, item) => acc + (item.closePrice || 0), 0)
  return sum / period
}

// 均线策略执行函数
const runMovingAverageStrategy = (allData) => {
  if (!Array.isArray(allData) || allData.length === 0 || 
      !Array.isArray(dateRange.value) || dateRange.value.length !== 2) {
    ElMessage.warning('策略执行失败：数据或日期范围无效')
    return []
  }

  const rangeEnd = dateRange.value[1]
  const testStart = getTestStartDate()
  const testEnd = testDate.value

  const testData = allData.filter(item => {
    const itemDate = item.date
    return itemDate >= testStart && itemDate <= testEnd
  })

  if (testData.length === 0) {
    ElMessage.warning('测试集无有效数据，无法执行策略')
    return []
  }

  const strategyState = {
    cash: 10000,
    holdShares: 0,
    totalAsset: 10000,
    returnRate: 0
  }

  const tradeRecords = []

  testData.forEach((dayData) => {
    const { date, closePrice = 0 } = dayData
    const currentPrice = Number(closePrice)
    const currentFundValue = strategyState.holdShares * currentPrice
    strategyState.totalAsset = strategyState.cash + currentFundValue
    strategyState.returnRate = ((strategyState.totalAsset - 10000) / 10000) * 100

    const record = {
      date,
      operation: '无操作',
      closePrice: currentPrice.toFixed(2),
      share: strategyState.holdShares,
      cash: strategyState.cash.toFixed(2),
      fundValue: currentFundValue.toFixed(2),
      total: strategyState.totalAsset.toFixed(2),
      returnRate: strategyState.returnRate
    }

    const currentShortMA = calculateMA(allData, date, MA_PARAMS.shortPeriod)
    const currentLongMA = calculateMA(allData, date, MA_PARAMS.longPeriod)
    const prevRecord = tradeRecords[tradeRecords.length - 1]
    const prevShortMA = prevRecord ? prevRecord.shortMA : null
    const prevLongMA = prevRecord ? prevRecord.longMA : null

    if (prevShortMA !== null && prevLongMA !== null && currentShortMA !== null && currentLongMA !== null) {
      if (prevShortMA <= prevLongMA && currentShortMA > currentLongMA) {
        if (strategyState.cash > currentPrice && currentPrice > 0) {
          const buyShares = Math.floor(strategyState.cash / currentPrice)
          const cost = buyShares * currentPrice

          strategyState.cash -= cost
          strategyState.holdShares += buyShares
          const newFundValue = strategyState.holdShares * currentPrice
          strategyState.totalAsset = strategyState.cash + newFundValue
          strategyState.returnRate = ((strategyState.totalAsset - 10000) / 10000) * 100

          record.operation = '买入'
          record.share = buyShares
          record.cash = strategyState.cash.toFixed(2)
          record.fundValue = newFundValue.toFixed(2)
          record.total = strategyState.totalAsset.toFixed(2)
          record.returnRate = strategyState.returnRate
        }
      } else if (prevShortMA >= prevLongMA && currentShortMA < currentLongMA) {
        if (strategyState.holdShares > 0) {
          const sellShares = strategyState.holdShares
          const income = sellShares * currentPrice

          strategyState.cash += income
          strategyState.holdShares = 0
          const newFundValue = 0
          strategyState.totalAsset = strategyState.cash + newFundValue
          strategyState.returnRate = ((strategyState.totalAsset - 10000) / 10000) * 100

          record.operation = '卖出'
          record.share = sellShares
          record.cash = strategyState.cash.toFixed(2)
          record.fundValue = newFundValue.toFixed(2)
          record.total = strategyState.totalAsset.toFixed(2)
          record.returnRate = strategyState.returnRate
        }
      }
    }

    record.shortMA = currentShortMA
    record.longMA = currentLongMA
    tradeRecords.push(record)
  })

  // 表格筛选：保留买入/卖出+最后一天记录
  if (tradeRecords.length > 0) {
    const filteredRecords = tradeRecords.filter(record => 
      record.operation === '买入' || record.operation === '卖出'
    )
    const lastDayRecord = tradeRecords[tradeRecords.length - 1]
    const isLastDayIncluded = filteredRecords.some(record => 
      record.date === lastDayRecord.date
    )
    if (!isLastDayIncluded) {
      filteredRecords.push(lastDayRecord)
    }
    filteredRecords.sort((a, b) => new Date(a.date) - new Date(b.date))
    
    tradeRecords.length = 0
    tradeRecords.push(...filteredRecords)
  }

  const lastRecord = tradeRecords[tradeRecords.length - 1]
  finalTotal.value = lastRecord ? Number(lastRecord.total) : 10000
  totalReturnRate.value = lastRecord ? lastRecord.returnRate : 0

  return tradeRecords
}

// 工具函数：计算指定数据系列的最大值和最小值
const calculateSeriesExtremes = (dataList, dateList) => {
  const validData = dataList
    .map((value, index) => ({ value, index }))
    .filter(item => item.value !== null && item.value > 0)

  if (validData.length === 0) {
    return { max: { value: null, date: '' }, min: { value: null, date: '' } }
  }

  const maxItem = validData.reduce((prev, curr) => 
    curr.value > prev.value ? curr : prev
  )
  const minItem = validData.reduce((prev, curr) => 
    curr.value < prev.value ? curr : prev
  )

  return {
    max: {
      value: maxItem.value,
      date: dateList[maxItem.index] || ''
    },
    min: {
      value: minItem.value,
      date: dateList[minItem.index] || ''
    }
  }
}

// -------------------------- 核心修改：1.修复最大值文案 2.新增买卖标记 --------------------------
// 工具函数：提取交易记录中的买入卖出数据（用于图表标记）
const extractTradeMarkers = (tradeRecords, dateList) => {
  if (!Array.isArray(tradeRecords) || tradeRecords.length === 0) {
    return []
  }

  // 筛选买入/卖出记录，匹配日期索引和价格
  return tradeRecords
    .filter(record => record.operation === '买入' || record.operation === '卖出')
    .map(record => {
      const dateIndex = dateList.indexOf(record.date)
      const price = Number(record.closePrice) || 0
      return {
        date: record.date,
        operation: record.operation,
        price: price,
        dateIndex: dateIndex,  // 用于图表定位
        share: record.share,   // 交易份数（用于tooltip）
        valid: dateIndex !== -1 && price > 0  // 有效性校验
      }
    })
    .filter(marker => marker.valid)  // 过滤无效标记
}

const renderChart = (allData) => {
  try {
    const container = document.getElementById('priceChartContainer')
    if (!container) {
      console.error('ECharts容器不存在')
      ElMessage.error('图表容器初始化失败')
      return
    }

    if (!priceChartInstance.value) {
      priceChartInstance.value = echarts.init(container)
      window.addEventListener('resize', () => priceChartInstance.value?.resize())
      window.addEventListener('beforeunload', () => {
        priceChartInstance.value?.dispose()
      })
    }

    // 1. 数据处理
    let fullDateList = []
    let datasetData = []
    let testsetData = []
    let priceMin = Infinity
    let priceMax = -Infinity
    let tradeMarkerData = []  // 存储买入卖出标记数据

    if (Array.isArray(allData) && allData.length > 0) {
      // 过滤无效数据
      const validData = allData.filter(item => {
        const isDateValid = item.date && formatDateToYmd(item.date) !== ''
        const isPriceValid = item.closePrice !== undefined && item.closePrice !== null && Number(item.closePrice) > 0
        return isDateValid && isPriceValid
      })

      // 计算价格范围（扩大1%避免标记点超出图表）
      validData.forEach(item => {
        const price = Number(item.closePrice)
        priceMin = Math.min(priceMin, price)
        priceMax = Math.max(priceMax, price)
      })
      if (priceMin === Infinity) {
        priceMin = 0
        priceMax = 100
      } else {
        const range = priceMax - priceMin
        priceMin = priceMin - range * 0.05  // 底部多留5%空间放买卖标记
        priceMax = priceMax + range * 0.01
      }

      // 生成基础数据
      fullDateList = validData.map(item => item.date)
      const rangeEnd = dateRange.value[1] || ''
      datasetData = validData.map(item => item.date <= rangeEnd ? Number(item.closePrice) : null)
      testsetData = validData.map(item => item.date > rangeEnd ? Number(item.closePrice) : null)

      // 计算极值标记
      const datasetExtremes = calculateSeriesExtremes(datasetData, fullDateList)
      const testsetExtremes = calculateSeriesExtremes(testsetData, fullDateList)
      chartMarkers.value = {
        datasetMax: datasetExtremes.max,
        datasetMin: datasetExtremes.min,
        testsetMax: testsetExtremes.max,
        testsetMin: testsetExtremes.min
      }

      // 新增：提取买入卖出标记数据
      tradeMarkerData = extractTradeMarkers(backtestTableData.value, fullDateList)
      console.log('提取的交易标记数据:', tradeMarkerData)

    } else {
      priceMin = 0
      priceMax = 100
      fullDateList = []
      datasetData = []
      testsetData = []
      tradeMarkerData = []
      chartMarkers.value = {
        datasetMax: { value: null, date: '' },
        datasetMin: { value: null, date: '' },
        testsetMax: { value: null, date: '' },
        testsetMin: { value: null, date: '' }
      }
    }

    // 2. 图表配置：修复最大值文案 + 新增买卖标记系列
    const chartOption = {
      grid: {
        id: 'priceChartGrid',
        left: '12%',
        right: '8%',
        bottom: '25%',
        top: '60px',
        containLabel: true,
        show: true,
        borderColor: '#f0f0f0'
      },
      xAxis: {
        gridId: 'priceChartGrid',
        type: 'category',
        boundaryGap: false,
        data: fullDateList,
        axisLabel: {
          show: true,
          rotate: 60,
          interval: (index, value) => {
            const totalCount = fullDateList.length
            if (totalCount <= 10) return true
            const intervalStep = Math.max(1, Math.floor(totalCount / 10))
            return index % intervalStep === 0
          },
          fontSize: 11,
          color: '#666',
          margin: 15,
          formatter: (value) => {
            if (!value) return '未知日期'
            const dateObj = new Date(value)
            if (isNaN(dateObj.getTime())) return value
            return `${String(dateObj.getMonth() + 1).padStart(2, '0')}-${String(dateObj.getDate()).padStart(2, '0')}`
          }
        },
        axisLine: {
          show: true,
          lineStyle: { color: '#999', width: 1.2 }
        },
        splitLine: {
          show: false
        },
        axisPointer: {
          show: true,
          type: 'line',
          lineStyle: { color: '#409eff', width: 1.5, opacity: 0.8 },
          label: {
            show: true,
            position: 'top',
            align: 'center',
            backgroundColor: 'rgba(64, 158, 255, 0.9)',
            color: '#fff',
            fontSize: 12,
            padding: [4, 8],
            borderRadius: 4,
            formatter: (params) => {
              return params.value || '未知日期'
            }
          }
        }
      },
      yAxis: {
        gridId: 'priceChartGrid',
        type: 'value',
        name: '收盘价（元）',
        nameTextStyle: {
          fontSize: 12,
          color: '#666',
          padding: [0, 0, 0, 15],
          fontWeight: 500
        },
        min: priceMin.toFixed(2),
        max: priceMax.toFixed(2),
        axisLabel: {
          show: true,
          fontSize: 12,
          color: '#666',
          formatter: (value) => Number(value).toFixed(2),
          margin: 10
        },
        axisLine: {
          show: true,
          lineStyle: { color: '#999', width: 1.2 }
        },
        splitLine: {
          show: true,
          lineStyle: { color: '#f7f7f7' }
        },
        axisPointer: {
          show: true,
          type: 'line',
          lineStyle: { color: '#409eff', width: 1.5, opacity: 0.8 }
        }
      },
      tooltip: {
        show: true,
        trigger: 'axis',
        triggerOn: 'mousemove',
        alwaysShowContent: true,
        ignore: false,
        backgroundColor: 'rgba(255, 255, 255, 0.95)',
        borderColor: '#409eff',
        borderWidth: 1.2,
        borderRadius: 6,
        padding: 12,
        textStyle: { fontSize: 13, color: '#333' },
        formatter: (params) => {
          let xAxisValue = params[0]?.axisValue || '未知日期'
          const dateObj = new Date(xAxisValue)
          if (!isNaN(dateObj.getTime())) {
            xAxisValue = `${dateObj.getFullYear()}-${String(dateObj.getMonth() + 1).padStart(2, '0')}-${String(dateObj.getDate()).padStart(2, '0')}`
          }

          const yAxisValue = params[0]?.value ? Number(params[0].value).toFixed(2) : '0.00'

          let dataInfo = ''
          params.forEach(series => {
            // 处理价格系列
            if (['数据集（训练期）', '测试集（回测期）'].includes(series.seriesName)) {
              if (series.value !== null && series.value > 0) {
                dataInfo += `<div style="margin-top:4px;">
                  <span style="display:inline-block;width:8px;height:8px;border-radius:50%;background:${series.color};margin-right:6px;"></span>
                  ${series.seriesName}：${Number(series.value).toFixed(2)} 元
                </div>`
              }
            }
            // 处理交易标记系列
            else if (series.seriesName === '交易标记') {
              const tradeInfo = series.data.tradeInfo
              if (tradeInfo) {
                dataInfo += `<div style="margin-top:4px;color:${tradeInfo.operation === '买入' ? '#67c23a' : '#f56c6c'};font-weight:500;">
                  📊 ${tradeInfo.operation}操作：${tradeInfo.price.toFixed(2)}元/份，共${tradeInfo.share}份
                </div>`
              }
            }
          })

          // 极值提示
          const currentValue = Number(params[0]?.value)
          if (currentValue) {
            const isDatasetMax = chartMarkers.value.datasetMax.value === currentValue
            const isDatasetMin = chartMarkers.value.datasetMin.value === currentValue
            const isTestsetMax = chartMarkers.value.testsetMax.value === currentValue
            const isTestsetMin = chartMarkers.value.testsetMin.value === currentValue
            
            if (isDatasetMax || isDatasetMin || isTestsetMax || isTestsetMin) {
              const markerType = isDatasetMax ? '数据集最大值' : 
                                 isDatasetMin ? '数据集最小值' : 
                                 isTestsetMax ? '测试集最大值' : '测试集最小值'
              dataInfo += `<div style="margin-top:4px;color:#e6a23c;font-weight:500;">
                ⚠️ 该点为${markerType}
              </div>`
            }
          }

          if (!dataInfo) {
            dataInfo = '<div style="margin-top:4px;font-size:12px;color:#999;">当前无匹配数据</div>'
          }

          return `<div>
            <div><span style="color:#409eff;font-weight:500;">日期：</span>${xAxisValue}</div>
            <div><span style="color:#409eff;font-weight:500;">价格：</span>${yAxisValue} 元</div>
            ${dataInfo}
          </div>`
        },
        position: (point, params, dom, rect, size) => {
          const x = point[0]
          const y = point[1]
          const tooltipWidth = size.contentSize[0]
          const tooltipHeight = size.contentSize[1]
          const chartWidth = rect.width
          const chartHeight = rect.height

          const posX = x + tooltipWidth > chartWidth ? x - tooltipWidth - 10 : x + 10
          const posY = y + tooltipHeight > chartHeight ? y - tooltipHeight - 10 : y + 10

          return [posX, posY]
        }
      },
      legend: {
        data: ['数据集（训练期）', '测试集（回测期）', '交易标记'],
        top: 20,
        left: 'center',
        textStyle: { fontSize: 13, color: '#666' },
        show: fullDateList.length > 0
      },
      series: [
        {
          name: '数据集（训练期）',
          type: 'line',
          data: datasetData,
          smooth: true,
          lineStyle: { color: '#409eff', width: 2.5 },
          itemStyle: { color: '#409eff' },
          showSymbol: false,
          emphasis: {
            itemStyle: { size: 8, shadowBlur: 4 },
            lineStyle: { width: 3 }
          },
          connectNulls: false,
          // 修复1：最大值标记文案（将错误的“最低”改为“最高”）
          markPoint: {
            symbol: 'pin',
            symbolSize: 50,
            silent: false,
            label: {
              show: true,
              position: 'top',
              fontSize: 12,
              fontWeight: 500,
              formatter: (params) => {
                // 核心修复：max对应“最高”，min对应“最低”
                const typeText = params.dataType === 'max' ? '最高' : '最低'
                return `${Number(params.value).toFixed(2)}\n${typeText}`
              }
            },
            data: [
              chartMarkers.value.datasetMax.value ? {
                type: 'max',
                name: '数据集最大值',
                value: chartMarkers.value.datasetMax.value,
                xAxis: fullDateList.indexOf(chartMarkers.value.datasetMax.date),
                itemStyle: { color: '#f56c6c' },
                label: { color: '#f56c6c' }
              } : null,
              chartMarkers.value.datasetMin.value ? {
                type: 'min',
                name: '数据集最小值',
                value: chartMarkers.value.datasetMin.value,
                xAxis: fullDateList.indexOf(chartMarkers.value.datasetMin.date),
                itemStyle: { color: '#67c23a' },
                label: { color: '#67c23a' }
              } : null
            ].filter(Boolean)
          }
        },
        {
          name: '测试集（回测期）',
          type: 'line',
          data: testsetData,
          smooth: true,
          lineStyle: { color: '#f56c6c', width: 2.5 },
          itemStyle: { color: '#f56c6c' },
          showSymbol: false,
          emphasis: {
            itemStyle: { size: 8, shadowBlur: 4 },
            lineStyle: { width: 3 }
          },
          connectNulls: false,
          // 修复2：测试集最大值标记文案
          markPoint: {
            symbol: 'pin',
            symbolSize: 50,
            silent: false,
            label: {
              show: true,
              position: 'top',
              fontSize: 12,
              fontWeight: 500,
              formatter: (params) => {
                const typeText = params.dataType === 'max' ? '最高' : '最低'
                return `${Number(params.value).toFixed(2)}\n${typeText}`
              }
            },
            data: [
              chartMarkers.value.testsetMax.value ? {
                type: 'max',
                name: '测试集最大值',
                value: chartMarkers.value.testsetMax.value,
                xAxis: fullDateList.indexOf(chartMarkers.value.testsetMax.date),
                itemStyle: { color: '#c0392b' },
                label: { color: '#c0392b' }
              } : null,
              chartMarkers.value.testsetMin.value ? {
                type: 'min',
                name: '测试集最小值',
                value: chartMarkers.value.testsetMin.value,
                xAxis: fullDateList.indexOf(chartMarkers.value.testsetMin.date),
                itemStyle: { color: '#27ae60' },
                label: { color: '#27ae60' }
              } : null
            ].filter(Boolean)
          }
        },
        // 新增3：买入卖出标记系列（scatter类型，显示B/S文本）
        {
          name: '交易标记',
          type: 'scatter',
          data: tradeMarkerData.map(marker => ({
            value: [marker.dateIndex, marker.price],  // [x轴索引, y轴价格]
            tradeInfo: marker,  // 附加交易信息（用于tooltip）
            symbol: `text:${marker.operation === '买入' ? 'B' : 'S'}`,  // 买入显示B，卖出显示S
            symbolSize: 24,  // 文本大小
            itemStyle: {
              color: marker.operation === '买入' ? '#67c23a' : '#f56c6c',  // 买入绿色，卖出红色
              fontWeight: 'bold'  // 文本加粗
            }
          })),
          silent: false,  // 允许触发tooltip
          emphasis: {
            itemStyle: {
              shadowBlur: 8,
              shadowColor: marker => marker.data.tradeInfo.operation === '买入' ? 'rgba(103, 194, 58, 0.5)' : 'rgba(245, 108, 108, 0.5)'
            }
          },
          // 标记位置调整（避免与折线重叠，略微向下偏移）
          position: (params) => {
            const [x, y] = params.value
            return [x, y + 15]  // y轴向下偏移15px
          }
        }
      ],
      graphic: {
        type: 'text',
        left: 'center',
        top: '50%',
        style: {
          text: '请先选择完整日期范围并点击"开始测试"',
          fontSize: 16,
          color: '#999'
        },
        invisible: fullDateList.length > 0
      }
    }

    // 渲染图表
    priceChartInstance.value.setOption(chartOption, true)

  } catch (error) {
    console.error('图表渲染失败:', error)
    ElMessage.error(`图表加载失败：${error.message}`)
  }
}

// 调用API获取数据并执行策略
const fetchDataAndRunStrategy = async () => {
  if (!instance || !$axios || !Array.isArray(dateRange.value) || dateRange.value.length !== 2) {
    ElMessage.error('执行失败：依赖参数无效')
    return
  }

  const globalLoading = ElLoading.service({
    text: '正在获取数据并执行策略...',
    fullscreen: true,
    background: 'rgba(255, 255, 255, 0.8)'
  })

  try {
    const dataStart = dateRange.value[0]
    const dataEnd = testDate.value
    const indexCode = indexSelected.value
    const st = formatDateToYmdNum(dataStart)
    const et = formatDateToYmdNum(dataEnd)

    if (!st || !et || !indexCode) {
      ElMessage.warning('参数格式错误（日期需为YYYY-MM-DD），请重新选择')
      return
    }

    const apiUrl = `https://api.zhituapi.com/hz/history/fsjy/${indexCode}/d`
    const res = await $axios.get(apiUrl, {
      params: { token: 'ZHITU_TOKEN_LIMIT_TEST', st, et },
      timeout: 15000
    })
    const apiRawData = res.data || []

    if (!Array.isArray(apiRawData) || apiRawData.length === 0) {
      ElMessage.warning('未获取到任何数据，请调整日期范围')
      return
    }

    // 数据清理
    const cleanedData = apiRawData
      .filter(item => item?.t && item?.c !== undefined && item?.c !== null)
      .map(item => ({
        date: formatDateToYmd(item.t),
        closePrice: Number(item.c) || 0
      }))
      .filter(item => item.date !== '' && item.closePrice > 0)
      .sort((a, b) => new Date(a.date) - new Date(b.date))

    console.log('清理后的数据（前5条）:', cleanedData.slice(0, 5))
    console.log('清理后的数据总数:', cleanedData.length)

    if (cleanedData.length === 0) {
      ElMessage.warning('无有效数据（日期或价格格式错误），请调整日期范围')
      return
    }

    priceChartData.value = cleanedData

    // 执行策略生成交易记录（用于图表买卖标记）
    if (strategySelected.value === 'moving-average') {
      backtestTableData.value = runMovingAverageStrategy(cleanedData)
    } else {
      const defaultRecord = [{
        date: cleanedData[cleanedData.length - 1].date,
        operation: '策略未实现',
        closePrice: cleanedData[cleanedData.length - 1].closePrice.toFixed(2),
        share: 0,
        cash: '10000.00',
        fundValue: '0.00',
        total: '10000.00',
        returnRate: 0
      }]
      backtestTableData.value = defaultRecord
      ElMessage.info('当前仅实现"均线策略（5日/20日）"，其他策略待扩展')
    }

    await nextTick()
    renderChart(cleanedData)  // 生成图表（包含买卖标记）
    isBacktestDone.value = true
    ElMessage.success('策略回测完成！')

  } catch (error) {
    console.error('数据获取/策略执行失败:', error)
    if (error.code === 'ECONNABORTED') {
      ElMessage.error('请求超时，请检查网络或缩小日期范围')
    } else if (error.response?.status) {
      ElMessage.error(`接口错误（${error.response.status}）：${error.response.data?.msg || '服务器异常'}`)
    } else {
      ElMessage.error(`处理失败：${error.message || '未知错误'}`)
    }
    backtestTableData.value = []
    isBacktestDone.value = false
  } finally {
    globalLoading.close()
  }
}

// 开始测试
const startTest = async () => {
  const missingParams = []
  if (!indexSelected.value) missingParams.push('指数')
  if (!Array.isArray(dateRange.value) || dateRange.value.length !== 2) missingParams.push('数据集日期范围')
  if (!testDate.value) missingParams.push('测试集结束日期')
  if (!strategySelected.value) missingParams.push('策略')

  if (missingParams.length > 0) {
    ElMessage.warning(`请补全以下必要参数：\n${missingParams.join('、')}`)
    return
  }

  const rangeEndDate = new Date(dateRange.value[1])
  const testDateObj = new Date(testDate.value)
  if (testDateObj <= rangeEndDate) {
    ElMessage.warning('测试集结束日期必须晚于数据集结束日期')
    return
  }

  backtestTableData.value = []
  finalTotal.value = 10000
  totalReturnRate.value = 0
  isBacktestDone.value = false
  chartMarkers.value = {
    datasetMax: { value: null, date: '' },
    datasetMin: { value: null, date: '' },
    testsetMax: { value: null, date: '' },
    testsetMin: { value: null, date: '' }
  }

  await fetchDataAndRunStrategy()
}

// 指数切换重置
const handleIndexChange = () => {
  priceChartData.value = []
  backtestTableData.value = []
  finalTotal.value = 10000
  totalReturnRate.value = 0
  isBacktestDone.value = false
  chartMarkers.value = {
    datasetMax: { value: null, date: '' },
    datasetMin: { value: null, date: '' },
    testsetMax: { value: null, date: '' },
    testsetMin: { value: null, date: '' }
  }
  if (priceChartInstance.value) {
    priceChartInstance.value.setOption({
      series: [
        { data: [], markPoint: { data: [] } },
        { data: [], markPoint: { data: [] } },
        { data: [] }  // 清空交易标记系列
      ],
      xAxis: { data: [] },
      graphic: { 
        style: { text: '请先选择日期范围并点击"开始测试"' }, 
        invisible: false 
      }
    })
  }
}

// 页面挂载初始化
onMounted(() => {
  fetchIndexList()
  nextTick(() => renderChart([]))
})

// 监听参数变化重置状态
watch([dateRange, testDate, strategySelected], () => {
  if (Array.isArray(dateRange.value) || testDate.value || strategySelected.value) {
    isBacktestDone.value = false
    chartMarkers.value = {
      datasetMax: { value: null, date: '' },
      datasetMin: { value: null, date: '' },
      testsetMax: { value: null, date: '' },
      testsetMin: { value: null, date: '' }
    }
  }
})
</script>

<style scoped>
.backtest-container {
  padding: 20px;
  background-color: #fff;
  min-height: calc(100vh - 64px);
}

.controls-container {
  padding: 16px;
  background-color: #f8f9fa;
  border-radius: 8px;
  margin-bottom: 24px;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
}

.chart-container-group {
  margin-bottom: 24px;
}

.chart-item {
  background-color: #f8f9fa;
  border-radius: 8px;
  padding: 16px;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
}

.chart-header {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  margin-bottom: 12px;
  flex-wrap: wrap;
  gap: 8px;
}

.chart-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.chart-header h3 {
  font-size: 16px;
  font-weight: 500;
  color: #333;
  margin: 0;
}

.chart-content {
  width: 100%;
  height: 500px;
  border-radius: 4px;
  background-color: #fff;
  overflow: visible !important;
  position: relative;
}

/* 优化标记样式 */
::v-deep .ec-mark-point {
  z-index: 10 !important;
}
::v-deep .ec-mark-point-label {
  white-space: nowrap !important;
  line-height: 1.2 !important;
}
/* 优化交易标记文本样式 */
::v-deep .ec-scatter-symbol text {
  font-family: 'Arial Bold', sans-serif !important;
  font-weight: 700 !important;
}

.backtest-result-container {
  background-color: #f8f9fa;
  border-radius: 8px;
  padding: 16px;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
}

.result-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 16px;
  flex-wrap: wrap;
  gap: 12px;
}

.result-header h3 {
  font-size: 16px;
  font-weight: 500;
  color: #333;
  margin: 0;
}

.result-summary {
  min-width: 500px;
}

.el-descriptions {
  --el-descriptions-border-color: #eee;
  --el-descriptions-title-color: #666;
  --el-descriptions-content-color: #333;
}

/* 小屏幕适配 */
@media (max-width: 992px) {
  .controls-container .el-row {
    flex-direction: column;
    gap: 16px !important;
  }
  .controls-container .el-col {
    width: 100% !important;
    max-width: 100% !important;
  }
  .chart-content {
    height: 450px;
  }
  .chart-item .grid {
    bottom: '30%' !important;
  }
  .xAxis .axisLabel {
    rotate: 75 !important;
    fontSize: 10 !important;
  }
  .result-header {
    flex-direction: column;
    align-items: flex-start;
  }
  .result-summary {
    min-width: 100%;
    width: 100%;
  }
  .el-table {
    font-size: 12px;
  }
  .el-table-column {
    width: auto !important;
    min-width: 100px;
  }
  .chart-tags {
    justify-content: flex-start;
  }
}
</style>
    